/**
 * 
 */
package com.heo.queue.task;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.log4j.Logger;

import com.heo.util.ByteHelper;
import com.heo.util.SequenceHelper;

/**
 * @author chichi
 *         该类保存了设备应答的信息
 *         当给设备重发指令时，由于是异步操作，所以需要将设备的应答信息保存在该集合中
 *         当向设备重发指令时，需要在该集合中查询上次发送的应答是否已经收到，如果已经收到，则不再发送。
 */
public class ReSendResponseInfo
{
  private static Logger log = Logger.getLogger(ReSendResponseInfo.class);
  private static final int LIVE_TIME = 60 * 10 * 1000;// 设备响应消息保存的时间，超过这个时间，就会被清除，单位：毫秒
  private static final int CHECK_TIME = 60 * 1000;// 多长时间检测一次，单位：毫秒

  /**
   * 结构如下：
   * [key]：deviceIMEI+包序号（sequenceId）
   * [value]：收到该应答的时间戳
   */
  private static Map<String, Long> responseMap = new ConcurrentHashMap<String, Long>();// 线程安全对象，记录当前每个socket连接对应的通道信息

  /**
   * 将应答的消息写入集合
   * 原子操作，集合为同步集合，所以不加sync关键字
   * 
   * @param deviceIMEI
   * @param sequenceId
   */
  public static void addResponseInfo(String deviceIMEI, Integer sequenceId)
  {
    responseMap.put(deviceIMEI + "_" + sequenceId, new Date().getTime());
  }

  /**
   * 查询设备应答的消息是否已经返回
   * 
   * @param deviceIMEI
   * @param sequenceId
   * @return
   */
  public static boolean isResponseInfo(String deviceIMEI, Integer sequenceId)
  {
    Long lastResponseTime = responseMap.get(deviceIMEI + "_" + sequenceId);
    if (lastResponseTime == null)
    {
      return false;
    }
    else
    {
      return true;
    }
  }

  static
  {
    // 启动一个检测过期的线程，每分钟检测一次。
    new Thread()
    {
      public void run()
      {
        while (true)
        {
          try
          {
            // 遍历所有设备应答包的响应时间
            for (String key : responseMap.keySet())
            {
              Long responseTime = responseMap.get(key);
              if (responseTime == null)
              {
                //有可能取出来的结果是null
                continue;
              }
              if ((new Date().getTime() - responseTime) > LIVE_TIME)
              {
                log.debug("删除过期的设备应答消息。[KEY]" + key);
                responseMap.remove(key);
              }
            }
            Thread.sleep(CHECK_TIME);
          }
          catch (InterruptedException e)
          {
            e.printStackTrace();
            log.error(e.getMessage(), e);
          }
        }
      }
    }.start();
  }
  
  public static void main(String[] args)
  {
    
  }
   
}
